

//===============================================================
#include "dashun.h"
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#define OBJ_MAX 128
#define VAR_LOCAL_MAX 1024
#define WC_BLANK_DELIMITER L' '
#define WC_LINE_FEED L'\n'
#define WC_SENTENCE_END L'。'
#define WC_PREDICATIVE_BELONG L'是' // 表语
#define WC_PREDICATE_CAN L'能' // 谓词
struct objque {//object queue
    wchar_t q[OBJ_MAX];
    int start, tail;
};

void init_objque(struct objque *Q) {
    Q->q[0] = L'\0';
    Q->start=0;
    Q->tail=0;
}

void add_objque(struct objque *Q, wchar_t wc) {
    Q->q[Q->tail++] = wc;
    Q->q[Q->tail] = L'\0';
} // 溢出风险

wchar_t *getdata_objque(struct objque *Q) {
    return Q->q;
}

int getsize_objque(struct objque *Q) {
    return Q->tail;
}

int cmp_objque(struct objque *Q, wchar_t *ws) {
    return wcsncmp(Q->q, ws, OBJ_MAX);
}

//---------------------------------------
struct VarPair {// 变量对
    wchar_t first[OBJ_MAX];
    wchar_t second[OBJ_MAX];
};

void init_VarPair(struct VarPair *P, wchar_t *k, wchar_t *v) {
    wcsncpy(P->first, k, OBJ_MAX);
    wcsncpy(P->second, v, OBJ_MAX);
} // 变量键值对

//-------
struct VarMap {  // 变量表
    struct VarPair vars[VAR_LOCAL_MAX];
    int top;
};

void init_VarMap(struct VarMap *M) {
    M->top = 0;
}

void add_VarMap(struct VarMap *M, wchar_t *k, wchar_t *v) {
    init_VarPair(&M->vars[M->top++], k, v);
}

void prt_VarMap(struct VarMap *M) {
    wprintf(L"------------------\n");
    for (int i=0; i < M->top; i++) {
        wprintf(L"%ls:\t%ls\n", M->vars[i].first, M->vars[i].second);
    }
    wprintf(L"------------------\n");
}

//---------------------------------------
int sensReadingStart(wchar_t wc) {
    return (wc == WC_LINE_FEED || wc == WC_SENTENCE_END) ? 0 : 1;
}

int IsPredicative_belong(wchar_t wc) {
    return (wc == WC_PREDICATIVE_BELONG) ? 1 : 0;
}

int IsPredict_can(wchar_t wc) {
    return (wc == WC_PREDICATE_CAN) ? 1 : 0;
}

int IsBlankWchar(wchar_t wc) {
    return wc == L'\0';
}

size_t lexer_zh(struct ObjMap *M, struct ObjList *L, char* path) {
    //setlocale(LC_ALL, "en_US.UTF-8")
    setlocale(LC_ALL, ""); // 空字符串自动检测

    FILE *file = fopen(path, "r");
    if (!file) {
        perror("打开文件失败");
        return 0;
    }

    //------------------- 初始化接收队列
    //struct objque sub, obj, act; // subject
    //init_objque(&sub);
    //init_objque(&obj);
    //init_objque(&act);
    int sens = 0; // readind sentence
    int sens_act = 0;
    int sens_obj = 0;

    //------------------- 初始化变量表
    struct VarMap vars;
    init_VarMap(&vars);


    wchar_t wc;
    while((wc  = fgetwc(file)) != WEOF) {
        if (ferror(file)) {
            perror("读取错误");
            break;
        }


        if ((!sens && sensReadingStart(wc)) || (sens && !sensReadingStart(wc))) {
            sens = !sens;
        }// 转换读取状态
        
        else if (sens && !sens_act && (IsPredicative_belong(wc) || IsPredict_can(wc))) {
            sens_obj = !sens_obj;
            continue;
        } // 阅读到了表语、谓词


        // 是否是互斥的？
        //
        // 有的句子没有带谓词
        //

        if (sens && !sens_act && !sens_obj) {
            add_objque(&sub, wc);
        } // 正在阅读 不是修饰 不是表语
        else if (sens && sens_obj) {
            add_objque(&obj, wc);
        } // 正在阅读宾语部分
        else if (!sens && getsize_objque(&sub)) {
            wchar_t *ws_sub = getdata_objque(&sub);
            wchar_t *ws_obj = getdata_objque(&obj);
            if (!IsBlankWchar(*ws_sub) && !IsBlankWchar(*ws_obj)) {
                add_VarMap(&vars, ws_sub, ws_obj);
            } // 继承关系时不可为空
            init_objque(&sub);
            init_objque(&act);
            init_objque(&obj);
            sens_act = 0; // 重置
            sens_obj = 0;
        } // 读完一句

    }

    prt_VarMap(&vars);
    fclose(file);
    return 0;
}